package com.hp.utils.excel.strategy.impl;


import com.hp.enums.ExcelCellTypeEnum;
import com.hp.utils.excel.ExcelConstraintResolve;
import com.hp.utils.excel.strategy.ConstraintTypeStrategy;
import jakarta.annotation.PostConstruct;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Objects;

/**
 * @author hp
 */
@Component
public class SelectConstraintTypeStrategy extends BasicConstraintStrategyFactory implements ConstraintTypeStrategy {
    @Override
    public void process(ExcelConstraintResolve resolve, Map<String, ExcelConstraintResolve> tempKeyMap, DataValidationHelper helper, Sheet hiddenSheet, Sheet sheet) {

        ExcelConstraintResolve tempResolve = StringUtils.isNotBlank(resolve.getKey()) ? tempKeyMap.get(resolve.getKey()) : null;
        if (Objects.nonNull(tempResolve)) {
            this.setSelectConstraint(resolve, helper, hiddenSheet, sheet, tempResolve);
        } else {

            if (StringUtils.isNotBlank(resolve.getKey())) {
                tempKeyMap.put(resolve.getKey(), resolve);
            }
            // 创建下拉的行和单元格
            this.createRowAndCell(hiddenSheet, resolve, resolve.getIndex());
            // 创建下拉的约束
            this.setSelectConstraint(resolve, helper, hiddenSheet, sheet, resolve);
        }

    }

    /**
     * 设置下拉框的约束
     */
    private void setSelectConstraint(ExcelConstraintResolve resolve, DataValidationHelper helper, Sheet hiddenSheet, Sheet sheet, ExcelConstraintResolve tempResolve) {
        // 创建下拉的约束
        DataValidationConstraint constraint = this.getSelectDataValidationConstraint(resolve, tempResolve, hiddenSheet.getSheetName(), helper);
        // 设置单元格验证
        this.setCellValidation(resolve, helper, constraint, sheet, true, true);
    }


    /**
     * 获取下拉框的数据验证约束
     */
    public DataValidationConstraint getSelectDataValidationConstraint(ExcelConstraintResolve resolve, ExcelConstraintResolve tempResolve, String sheetName, DataValidationHelper helper) {
        String excelLine = this.getExcelLine(tempResolve.getIndex());
        String refers = "=" + sheetName + "!$" + excelLine + "$1:$" + excelLine + "$" + resolve.getSource().length;
        return helper.createFormulaListConstraint(refers);
    }


    /**
     * 返回excel列标A-Z-AA-ZZ
     *
     * @param num 列数
     * @return java.lang.String
     */
    private String getExcelLine(int num) {
        String line = "";
        int first = num / 26;
        int second = num % 26;
        if (first > 0) {
            line = (char) ('A' + first - 1) + "";
        }
        line += (char) ('A' + second) + "";
        return line;
    }

    /**
     * 创建下拉的行和单元格
     */
    private void createRowAndCell(Sheet hiddenSheet, ExcelConstraintResolve excelSelectedResolve, Integer index) {
        for (int i = 0, length = excelSelectedResolve.getSource().length; i < length; i++) {
            Row row = hiddenSheet.getRow(i);
            if (null == row) {
                row = hiddenSheet.createRow(i);
            }
            Cell cell = row.getCell(index);
            if (null == cell) {
                cell = row.createCell(index);
            }
            cell.setCellValue(excelSelectedResolve.getSource()[i]);
        }
    }

    @PostConstruct
    public void init() {
        CELL_TYPE_STRATEGY_MAP.put(ExcelCellTypeEnum.SELECT.getType(), this);
    }
}